package com.leaf.spring.y201907.day24.config;

import java.util.HashMap;
import java.util.Map;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * rabbitmq 配置
 * 
 * @Title:
 * @Description:
 * @Author: leaf
 * @Since:2019年7月25日
 * @Version:1.1.0
 */
@Configuration
public class MqConfiguration {

	// 配置连接
	@Bean
	public ConnectionFactory connectionFactory() {
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory("192.168.3.152", 5672);
		connectionFactory.setUsername("leaf");
		connectionFactory.setPassword("123");
		connectionFactory.setVirtualHost("testHost");
		// 发送方确认模式
		connectionFactory.setPublisherConfirms(true);
		return connectionFactory;
	}

	// 交换机
	@Bean
	public DirectExchange defaultExchange() {
		return new DirectExchange("leafExchange1");
	}

	// 队列
	@Bean
	public Queue queue() {
		// 死信交换机
		Map<String, Object> map = new HashMap<>();
		// 设置消息的过期时间，单位毫秒
		map.put("x-message-ttl", 10000);
		// 设置附带的死信交换机
		map.put("x-dead-letter-exchange", "exchange.dlx");
		// 指定重定向的路由键，消息作废之后可以决定需不需要更改他的路由键，如果需要，就在这里指定
		map.put("x-dead-letter-routing-key", "dead.order");
		// 名字 是否持久化
		return new Queue("testQueue", false);
	}

	@Bean
	public Binding binding() {
		// 绑定一个队列
		// to 绑定到哪个交换机上面
		// with 绑定的路由键 routingKey
		return BindingBuilder.bind(queue()).to(defaultExchange()).with("direct.key");
	}

	@Bean
	public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
		// 开启mandatory模式(失败回调)
		rabbitTemplate.setMandatory(true);
		// 指定失败回调接口的实现类
		rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {

			@Override
			public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
				System.out.println(message);
				System.out.println(replyCode);
				System.out.println(replyText);
				System.out.println(exchange);
				System.out.println(routingKey);
			}
		});
		// 发送方确认模式
		rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {

			@Override
			public void confirm(CorrelationData correlationData, boolean ack, String cause) {
				System.out.println(correlationData);
				System.out.println(ack);
				System.out.println(cause);
			}
		});
		return rabbitTemplate;
	}

	@Bean
	public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
		SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
		factory.setConnectionFactory(connectionFactory);
		// 设置消息确认方式为手动确认
		factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
		// 设置消息预存数量
		factory.setPrefetchCount(10);
		return factory;
	}

}
